home *** CD-ROM | disk | FTP | other *** search
/ Greenhouse Effect Detection Expriment / NASA Greenhouse Effect Detection Expriment 1992 - Disc 2.iso / software / dos / cdf22pc / src / lib / cdfcre.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-09  |  13.3 KB  |  516 lines

  1. /******************************************************************************
  2. *
  3. *  NSSDC/CDF                        CDF 'create' operations.
  4. *
  5. *  Version 1.0, 10-Feb-92, ST Systems (STX)
  6. *
  7. *  Modification history:
  8. *
  9. *   V1.0  10-Feb-92, J Love    Original version (was part of `cdflib.c').
  10. *
  11. ******************************************************************************/
  12.  
  13. #include "cdflib.h"
  14.  
  15. /******************************************************************************
  16. * CDFcre.
  17. ******************************************************************************/
  18.  
  19. CDFstatus CDFcre (ap, item, fnc)
  20. va_list *ap;
  21. long item;
  22. long *fnc;
  23. {
  24. CDFstatus Pstatus = CDF_OK;
  25. CDFstatus Tstatus;
  26.  
  27. switch (item) {
  28.   case CDF_: {
  29.     CDFid *id;
  30.     char *CDFname;
  31.     long numDims;
  32.     long *dimSizes;
  33.     char cdfname[CDF_PATHNAME_LEN+1];
  34.     char cdfnameX[CDF_PATHNAME_LEN+4+1]; /* +4+1 for .CDF and NUL-terminator */
  35.     CDFid newid;
  36.     long i, Nbytes;
  37.     File *tmpfp;
  38.     struct cdfSTRUCT *CDF;
  39.     long eof;                /* maintained until GDR created */
  40.  
  41.     CDFname = va_arg (*ap, char *);
  42.     numDims = va_arg (*ap, long);
  43.     dimSizes = va_arg (*ap, long *);
  44.     id = va_arg (*ap, CDFid *);
  45.  
  46.     if (numDims < 0 || numDims > CDF_MAX_DIMS) return BAD_NUM_DIMS;
  47.     for (i = 0; i < numDims; i++) if (dimSizes[i] < 1) return BAD_DIM_SIZE;
  48.  
  49.     if (strlen(CDFname) > CDF_PATHNAME_LEN) {
  50.       strncpy (cdfname, CDFname, CDF_PATHNAME_LEN);
  51.       cdfname[CDF_PATHNAME_LEN] = NUL;
  52.       STATUSdisp (CDF_NAME_TRUNC, Pstatus);
  53.     }
  54.     else
  55.       strcpy (cdfname, CDFname);
  56.  
  57. #if defined(vms)  /** remove trailing blanks if VMS **/
  58.     for (i = strlen(cdfname) - 1; i >= 0; i--) {
  59.        if (cdfname[i] == ' ')
  60.      cdfname[i] = NUL;
  61.        else
  62.      break;
  63.     }
  64. #endif
  65.     if ( ! validCDFname(cdfname)) return BAD_CDF_NAME;
  66.  
  67.     /** find CDFid to use **/
  68.  
  69.     for (newid = 0; newid < CDF_MAX_CDFS; newid++)
  70.        if (_CDFs[newid] == NULL) break;
  71.  
  72.     if (newid == CDF_MAX_CDFS) return TOO_MANY_CDFS;
  73.  
  74.     /* Check if the CDF already exists */
  75.  
  76.     ExpandPath (cdfname, cdfnameX);
  77.     strcat (cdfnameX, ".cdf");
  78.  
  79.     if (IsReg(cdfnameX)) return CDF_EXISTS;
  80.  
  81. #if defined(vms) | defined(__MSDOS__)
  82.     tmpfp = OpenFile (cdfnameX,"w+b");
  83. #endif
  84. #if defined(unix)
  85.     tmpfp = OpenFile (cdfnameX,"w+");
  86. #endif
  87.     if (tmpfp == NULL) return CDF_CREATE_ERROR;
  88.  
  89.     _CDFs[newid] = (struct cdfSTRUCT *) malloc (sizeof(struct cdfSTRUCT));
  90.     if (_CDFs[newid] == NULL) return BAD_MALLOC;  /*CLEAN UP!*/
  91.  
  92.     CDF = _CDFs[newid];
  93.  
  94.     CDF->status = CDF_READ_WRITE;
  95.     CDF->fp = tmpfp;
  96.  
  97.     strcpy (CDF->filename, cdfname);
  98.     CDF->id = newid;
  99.  
  100.     eof = 0;
  101.  
  102.     /*** Set up magic number(s) ***/
  103.  
  104.     CDF->magic_number = V2_MAGIC_NUMBER;
  105.     eof += sizeof(Int32);
  106.     eof += sizeof(Int32);          /* magic number written twice */
  107.  
  108.     /*** Set up CDR ***/
  109.  
  110.     CDF->CDRoffset = V2_CDR_OFFSET;
  111.     CDF->CDR.RecordSize = CDR_BASE_SIZE + CDF_COPYRIGHT_LEN;
  112.     CDF->CDR.RecordType = CDR_;
  113.  
  114.     /*** CDR.GDRoffset calculated below ***/
  115.  
  116.     CDF->CDR.Version = CDF_LIBRARY_VERSION;
  117.     CDF->CDR.Release = CDF_LIBRARY_RELEASE;
  118.     CDF->CDR.Increment = CDF_LIBRARY_INCREMENT;
  119.     CDF->CDR.Encoding = _CDFhostEncoding;
  120.  
  121.     CDF->CDR.Flags = 0;
  122.  
  123.     setbit (CDF->CDR.Flags, CDF_MAJORITY_BIT);  /* majority --> ROW_MAJOR */
  124.     clrbit(CDF->CDR.Flags, CDF_FORMAT_BIT);     /* format --> MULTI_FILE */
  125.  
  126.     CDF->CDR.rfuA = 0;
  127.     CDF->CDR.rfuB = 0;
  128.     CDF->CDR.rfuD = -1;
  129.     CDF->CDR.rfuE = -1;
  130.  
  131.     strcpy (CDF->CDR.copyright, _CDF_CopyRight);
  132.  
  133.     eof = CDF->CDRoffset + CDF->CDR.RecordSize;
  134.  
  135.     /*** Set up GDR ***/
  136.  
  137.     CDF->GDRoffset = eof;
  138.     CDF->CDR.GDRoffset = CDF->GDRoffset;
  139.  
  140.     /*** GDR.RecordSize calculated below ***/
  141.  
  142.     CDF->GDR.RecordType = GDR_;
  143.     CDF->GDR.VDRhead = 0;
  144.     CDF->GDR.garbage1 = 0;    /* in V2.0 CDFs this field
  145.                      contained a random value */
  146.     CDF->GDR.ADRhead = 0;
  147.  
  148.     /*** GDR.eof calculated below ***/
  149.  
  150.     CDF->GDR.NumVar = 0;
  151.     CDF->GDR.NumAttr = 0;
  152.     CDF->GDR.MaxRec = -1;
  153.     CDF->GDR.NumDims = numDims;
  154.  
  155.     CDF->GDR.rfuA = 0;
  156.     CDF->GDR.rfuB = 0;
  157.     CDF->GDR.rfuC = 0;
  158.     CDF->GDR.rfuD = -1;
  159.     CDF->GDR.rfuE = -1;
  160.  
  161.     if (numDims > 0) {
  162.       CDF->GDR.DimSizes = (Int32 *) malloc (numDims * sizeof(Int32));
  163.       if (CDF->GDR.DimSizes == NULL) return BAD_MALLOC;
  164.       for (i = 0; i < numDims; i++) CDF->GDR.DimSizes[i] = dimSizes[i];
  165.     }
  166.     else
  167.       CDF->GDR.DimSizes = NULL;
  168.  
  169.     CDF->GDR.RecordSize = GDR_BASE_SIZE + CDF->GDR.NumDims*sizeof(Int32);
  170.     CDF->GDR.eof = CDF->GDRoffset + CDF->GDR.RecordSize;
  171.  
  172.     CDF->recnum = 0;
  173.     CDF->reccount = 1;
  174.     CDF->recinterval = 1;
  175.  
  176.     if (numDims > 0) {
  177.       Nbytes = numDims * sizeof(long);
  178.  
  179.       CDF->indices = (long *) malloc (Nbytes);
  180.       if (CDF->indices == NULL) return BAD_MALLOC; /* CLEAN UP */
  181.       CDF->counts = (long *) malloc (Nbytes);
  182.       if (CDF->counts == NULL) return BAD_MALLOC; /* CLEAN UP */
  183.       CDF->intervals = (long *) malloc (Nbytes);
  184.       if (CDF->intervals == NULL) return BAD_MALLOC; /* CLEAN UP */
  185.  
  186.       for (i = 0; i < numDims; i++) {
  187.      CDF->indices[i] = 0;
  188.      CDF->counts[i] = dimSizes[i];
  189.      CDF->intervals[i] = 1;
  190.       }
  191.     }
  192.     else {
  193.       CDF->indices = NULL;
  194.       CDF->counts = NULL;
  195.       CDF->intervals = NULL;
  196.     }
  197.  
  198.     CDF->CURentryNum = RESERVED_ENTRYNUM;
  199.  
  200.     CDF->attrHead = NULL;
  201.     CDF->attrTail = NULL;
  202.  
  203.     CDF->varHead = NULL;
  204.     CDF->varTail = NULL;
  205.     for (i = 0; i < CDF_MAX_VARS; i++) CDF->var[i] = NULL;
  206.  
  207.     CDF->CURattr = NULL;
  208.     CDF->CURentry = NULL;
  209.     CDF->CURvar = NULL;
  210.  
  211.     _CURcdf = CDF;
  212.  
  213.     *id = newid;
  214.     break;
  215.   }
  216.   case VAR_: {
  217.     long *varnum;
  218.     long dataType;
  219.     long numElements;
  220.     long recVariance;
  221.     long *dimVariances;
  222.     char *varName;
  223.     char truncname[CDF_VAR_NAME_LEN+1];
  224.     char openname[CDF_PATHNAME_LEN+6+1];       /* +6+1 for .Vnnnn and
  225.                               NUL-terminator */
  226.     long newvarnum;
  227.     long i;
  228.     File *fp;
  229.     struct varSTRUCT *Var;
  230.     struct varSTRUCT *ntlVar;              /* next-to-last Var */
  231.     long Nbytes;
  232.  
  233.     varName = va_arg (*ap, char *);
  234.     dataType = va_arg (*ap, long);
  235.     numElements = va_arg (*ap, long);
  236.     recVariance = va_arg (*ap, long);
  237.     dimVariances = va_arg (*ap, long *);
  238.     varnum = va_arg (*ap, long *);
  239.  
  240.     if (_CURcdf == NULL) return NO_CDF_SELECTED;
  241.     if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
  242.     if ( ! validDataType(dataType)) return BAD_DATA_TYPE;
  243.     if (numElements < 1) return BAD_NUM_ELEMS;
  244.  
  245.     if (dataType != CDF_CHAR && dataType != CDF_UCHAR)
  246.       if (numElements != 1) return BAD_NUM_ELEMS;
  247.  
  248.     if (strlen(varName) > CDF_VAR_NAME_LEN) {
  249.       strncpy (truncname, varName, CDF_VAR_NAME_LEN);
  250.       truncname[CDF_VAR_NAME_LEN] = NUL;
  251.       STATUSdisp (VAR_NAME_TRUNC, Pstatus);
  252.     }
  253.     else
  254.       strcpy (truncname, varName);
  255.  
  256.     if ( ! validVarName(truncname)) return BAD_VAR_NAME;
  257.  
  258.     Var = _CURcdf->varHead;
  259.     while (Var != NULL) {
  260.       if (strcmpITB(Var->VDR.Name,truncname) == 0) return VAR_EXISTS;
  261.       Var = Var->varNext;
  262.     }
  263.  
  264.     if (_CURcdf->GDR.NumVar >= CDF_MAX_VARS) return TOO_MANY_VARS;
  265.  
  266.     if (_CURcdf->status == CDF_READ_ONLY) {
  267.       Tstatus = ReopenCDFforWrite (_CURcdf);
  268.       STATUSdisp (Tstatus, Pstatus);
  269.     }
  270.  
  271.     /* Look for empty variable number slot */
  272.  
  273.     for (newvarnum = 0; newvarnum < CDF_MAX_VARS; newvarnum++)
  274.        if (_CURcdf->var[newvarnum] == NULL) break;
  275.  
  276.     if (bitclr(_CURcdf->CDR.Flags, CDF_FORMAT_BIT)) {
  277.       sprintf (openname, "%s.v%d", _CURcdf->filename, newvarnum);
  278. #if defined(vms) | defined(__MSDOS__)
  279.       fp = OpenFile (openname,"w+b");
  280. #endif
  281. #if defined(unix)
  282.       fp = OpenFile (openname,"w+");
  283. #endif
  284.       if (fp == NULL) return VAR_CREATE_ERROR;
  285.       Close (fp);
  286.     }
  287.  
  288.     Var = (struct varSTRUCT *) malloc (sizeof(struct varSTRUCT));
  289.     if (Var == NULL) return BAD_MALLOC;    /* CLEAN UP! */
  290.  
  291.     if (_CURcdf->varHead == NULL) {  /* first variable */
  292.       ntlVar = (struct varSTRUCT *) NULL;
  293.       _CURcdf->varHead = Var;
  294.       _CURcdf->varTail = Var;
  295.     }
  296.     else {
  297.       ntlVar = _CURcdf->varTail;
  298.       _CURcdf->varTail->varNext = Var;
  299.       _CURcdf->varTail = Var;
  300.     }
  301.  
  302.     Var->varNext = (struct varSTRUCT *) NULL;
  303.  
  304.     if (bitclr(_CURcdf->CDR.Flags,CDF_FORMAT_BIT)) {
  305.       Var->fp = fp;        /* variable data in .Vnn */
  306.       Var->status = VAR_CLOSED;
  307.     }
  308.     else {
  309.       Var->fp = _CURcdf->fp;    /* variable data in .CDF */
  310.       Var->status = NO_VAR_FILE;
  311.     }
  312.  
  313.     /*** Set up VDR ***/
  314.  
  315.     Var->VDRoffset = _CURcdf->GDR.eof;
  316.  
  317.     Var->VDR.RecordSize = VDR_BASE_SIZE +
  318.               CDF_VAR_NAME_LEN +
  319.               CDF_VAR_FILE_NAME_LEN +
  320.               _CURcdf->GDR.NumDims*sizeof(Int32);
  321.     Var->VDR.RecordType = VDR_;
  322.     Var->VDR.VDRnext = 0;
  323.     Var->VDR.DataType = dataType;
  324.     Var->VDR.MaxRec = -1;
  325.     Var->VDR.VXRhead = 0;
  326.     Var->VDR.VXRtail = 0;
  327.  
  328.     Var->VDR.Flags = 0;
  329.  
  330.     if (recVariance)
  331.       setbit(Var->VDR.Flags,VAR_RECVARY_BIT);
  332.     else
  333.       clrbit(Var->VDR.Flags,VAR_RECVARY_BIT);
  334.  
  335.     clrbit(Var->VDR.Flags,VAR_FILLVALUE_BIT);
  336.  
  337.     Var->VDR.rfuA = 0;
  338.     Var->VDR.rfuB = 0;
  339.     Var->VDR.rfuC = -1;
  340.  
  341.     Var->VDR.REFvarNum = -1;
  342.     Var->VDR.REFfilename[0] = '\0';
  343.     Var->VDR.NumElem = numElements;
  344.     Var->VDR.Num = newvarnum;
  345.  
  346.     Var->VDR.rfuD = -1;
  347.     Var->VDR.NextendRecs = 0;
  348.  
  349.     strcpy (Var->VDR.Name, truncname);
  350.  
  351.     if (_CURcdf->GDR.NumDims > 0) {
  352.       Var->VDR.DimVarys = (Int32 *) malloc (_CURcdf->GDR.NumDims *
  353.                         sizeof(Int32));
  354.       if (Var->VDR.DimVarys == NULL) return BAD_MALLOC; /* CLEAN UP! */
  355.  
  356.       for (i = 0; i < _CURcdf->GDR.NumDims; i++)
  357.      if (dimVariances[i])
  358.        Var->VDR.DimVarys[i] = VARY;
  359.      else
  360.        Var->VDR.DimVarys[i] = NOVARY;
  361.     }
  362.     else
  363.       Var->VDR.DimVarys = NULL;
  364.  
  365.     Var->VDR.FillValue = NULL;
  366.  
  367.     _CURcdf->GDR.eof += Var->VDR.RecordSize;
  368.  
  369.     /*** point next-to-last VDR (or GDR) to this VDR ***/
  370.  
  371.     if (ntlVar == NULL)
  372.       _CURcdf->GDR.VDRhead = Var->VDRoffset;
  373.     else
  374.       ntlVar->VDR.VDRnext = Var->VDRoffset;
  375.  
  376.     /*** allocate and set up variable control data ***/
  377.  
  378.     if (_CURcdf->GDR.NumDims > 0) {
  379.       Nbytes = _CURcdf->GDR.NumDims * sizeof(long);
  380.       Var->products = (long *) malloc (Nbytes);
  381.       if (Var->products == NULL) return BAD_MALLOC; /* CLEAN UP */
  382.       Var->hypProducts = (long *) malloc (Nbytes);
  383.       if (Var->hypProducts == NULL) return BAD_MALLOC; /* CLEAN UP */
  384.       Var->hypIndices = (long *) malloc (Nbytes);
  385.       if (Var->hypIndices == NULL) return BAD_MALLOC; /* CLEAN UP */
  386.       Var->hypTops = (long *) malloc (Nbytes);
  387.       if (Var->hypTops == NULL) return BAD_MALLOC; /* CLEAN UP */
  388.     }
  389.     else {
  390.       Var->products = NULL;
  391.       Var->hypProducts = NULL;
  392.       Var->hypIndices = NULL;
  393.       Var->hypTops = NULL;
  394.     }
  395.  
  396.     Var->seqValueOffset = 0;
  397.  
  398.     calcVarParms (_CURcdf, Var);
  399.  
  400.     Var->vixHead = (struct vixSTRUCT *) NULL;
  401.     Var->vixTail = (struct vixSTRUCT *) NULL;
  402.  
  403.     /*** tally another variable ***/
  404.  
  405.     _CURcdf->GDR.NumVar++;
  406.  
  407.     _CURcdf->var[newvarnum] = Var;
  408.     _CURcdf->CURvar = Var;
  409.  
  410.     *varnum = newvarnum;
  411.     break;
  412.   }
  413.   case ATTR_: {
  414.     long *attrnum;
  415.     char *attrname;
  416.     long scope;
  417.     struct attrSTRUCT *Attr;
  418.     struct attrSTRUCT *ntlAttr;    /* next-to-last Attr */
  419.     char truncname[CDF_ATTR_NAME_LEN+1];
  420.  
  421.     attrname = va_arg (*ap, char *);
  422.     scope = va_arg (*ap, long);
  423.     attrnum = va_arg (*ap, long *);
  424.  
  425.     if (_CURcdf == NULL) return NO_CDF_SELECTED;
  426.     if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
  427.     if ( ! validAttrScope(scope)) return BAD_SCOPE;
  428.  
  429.     if (strlen(attrname) > CDF_ATTR_NAME_LEN) {
  430.       strncpy (truncname, attrname, CDF_ATTR_NAME_LEN);
  431.       truncname[CDF_ATTR_NAME_LEN] = NUL;
  432.       STATUSdisp (ATTR_NAME_TRUNC, Pstatus);
  433.     }
  434.     else
  435.       strcpy (truncname, attrname);
  436.  
  437.     if ( ! validAttrName(truncname)) return BAD_ATTR_NAME;
  438.  
  439.     Attr = _CURcdf->attrHead;
  440.     while (Attr != NULL) {
  441.       if (strcmpITB(truncname,Attr->ADR.Name) == 0) return ATTR_EXISTS;
  442.       Attr = Attr->attrNext;
  443.     }
  444.  
  445.     if (_CURcdf->status == CDF_READ_ONLY) {
  446.       Tstatus = ReopenCDFforWrite (_CURcdf);
  447.       STATUSdisp (Tstatus, Pstatus);
  448.     }
  449.  
  450.     Attr = (struct attrSTRUCT *) malloc (sizeof(struct attrSTRUCT));
  451.     if (Attr == NULL) return BAD_MALLOC;
  452.  
  453.     if (_CURcdf->attrHead == NULL) {  /* first attribute */
  454.       ntlAttr = (struct attrSTRUCT *) NULL;
  455.       _CURcdf->attrHead = Attr;
  456.       _CURcdf->attrTail = Attr;
  457.     }
  458.     else {
  459.       ntlAttr = _CURcdf->attrTail;
  460.       _CURcdf->attrTail->attrNext = Attr;
  461.       _CURcdf->attrTail = Attr;
  462.     }
  463.  
  464.     Attr->attrNext = (struct attrSTRUCT *) NULL;
  465.  
  466.     /*** Set up ADR ***/
  467.  
  468.     Attr->ADRoffset = _CURcdf->GDR.eof;
  469.  
  470.     Attr->ADR.RecordSize = ADR_BASE_SIZE + CDF_ATTR_NAME_LEN;
  471.     Attr->ADR.RecordType = ADR_;
  472.     Attr->ADR.ADRnext = 0;
  473.     Attr->ADR.AEDRhead = 0;
  474.     Attr->ADR.Scope = scope;
  475.     Attr->ADR.Num = _CURcdf->GDR.NumAttr;
  476.     Attr->ADR.NumEntries = 0;
  477.     Attr->ADR.MaxEntry = -1;
  478.  
  479.     Attr->ADR.rfuA = 0;
  480.     Attr->ADR.rfuB = 0;
  481.     Attr->ADR.rfuC = 0;
  482.     Attr->ADR.rfuD = -1;
  483.     Attr->ADR.rfuE = -1;
  484.  
  485.     strcpy (Attr->ADR.Name, truncname);
  486.  
  487.     _CURcdf->GDR.eof += Attr->ADR.RecordSize;
  488.  
  489.     /*** point next-to-last ADR (or GDR) to this ADR ***/
  490.  
  491.     if (ntlAttr == NULL)
  492.       _CURcdf->GDR.ADRhead = Attr->ADRoffset;
  493.     else
  494.       ntlAttr->ADR.ADRnext = Attr->ADRoffset;
  495.  
  496.     /*** set up entry list ***/
  497.  
  498.     Attr->entryHead = NULL;
  499.     Attr->entryTail = NULL;
  500.  
  501.     _CURcdf->GDR.NumAttr++;
  502.  
  503.     _CURcdf->CURattr = Attr;
  504.     _CURcdf->CURentry = NULL;        /* no entries in attr. yet */
  505.  
  506.     *attrnum = Attr->ADR.Num;
  507.     break;
  508.   }
  509.   default: {
  510.     *fnc = item;
  511.     break;
  512.   }
  513. }
  514. return Pstatus;
  515. }
  516.